<?php

namespace App\Logic;

use Common\Logic\BaseLogic;

class SurveyLogic extends BaseLogic
{
    private $userModel;

    private $panelid = 294;
    private $cryptKey = 'LxuOYSkC2bZeMX6Q';

    public function __construct()
    {
        parent::__construct();
        $this->userModel = D('User');
    }

    /**
     * 获取panelid.
     *
     * @return void
     */
    public function getPanelid()
    {
        return $this->panelid;
    }

    public function getCrypt($userId)
    {
        $panelid = $this->panelid;
        $str = "$userId:$panelid:".time();

        return $this->encrypt($this->cryptKey, $str);
    }

    public function getAttrStr($userId)
    {
        $userInfo = $this->userModel->where(array(
            'id' => $userId,
            'user_state' => 1,
        ))->find();

        if (empty($userInfo)) {
            return static::$res->err('未找到用户');
        }

        $sex = $userInfo['sex'];
        $prov = $userInfo['prov'];
        $city = $userInfo['city'];
        $birthday = $userInfo['birthday'];

        if (empty($sex)) {
            $sex = 1;
        }

        if (empty($prov) || empty($city) || empty($birthday)) {
            return static::$res->err('参数缺失');
        }

        //格式化生日时间
        $birthday = date('Ymd', \strtotime($birthday));

        //所属市级行政区划
        $cityList = C('CITY_LIST');
        $areaId = $cityList[$city];
        if (empty($areaId)) {
            $provList = C('PROV_LIST');
            $areaId = $provList[$prov];
        }
        if (empty($areaId)) {
            $areaId = C('AREA_OTHER');
        }

        $str = "$sex:$birthday:$areaId";
        $attr = $this->encrypt($this->cryptKey, $str);

        return static::$res->suc('成功', $attr);
    }

    /**
     * 校验hash.
     *
     * @param [type] $data
     *
     * @return void
     */
    public function checkHash($data)
    {
        //验证参数的完整性
        $flied = array('member_id', 'survey_id', 'grant_times', 'point', 'status', 'survey_name');
        foreach ($flied as $val) {
            if (null === $data[$val] || '' === $data[$val]) {
                return static::$res->err('参数缺失');
            }
        }

        $hash = $data['hash'];
        $cHash = $this->getHashSample($this->cryptKey, $data);

        if ($hash != $cHash) {
            return static::$res->err('校验失败');
        }

        return static::$res->suc('校验成功');
    }

    /**
     * 获取校验hash.
     *
     * @param [type] $encryptKey
     * @param [type] $parameters
     *
     * @return void
     */
    private function getHashSample($encryptKey, $parameters)
    {
        if (isset($parameters['hash'])) {
            unset($parameters['hash']);
        }
        $parameters['survey_name'] = \urlencode($parameters['survey_name']);
        ksort($parameters, SORT_STRING);
        $tmp_values = [];
        foreach ($parameters as $value) {
            $tmp_values[] = $value;
        }
        $tmp_values[] = $encryptKey;

        return hash('sha256', implode($tmp_values));
    }

    /**
     * 加密.
     *
     * @param [type] $key
     * @param [type] $text
     *
     * @return void
     */
    private function encrypt($key, $text)
    {
        $size = mcrypt_get_block_size('blowfish', 'ecb');
        $input = $this->pkcs5_pad($text, $size);
        $td = mcrypt_module_open('blowfish', '', 'ecb', '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $key, $iv);
        $data = mcrypt_generic($td, $input);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);

        $data = bin2hex($data);

        return $data;
    }

    /**
     * 解密.
     *
     * @param [type] $key
     * @param [type] $text
     *
     * @return void
     */
    private function decrypt($key, $text)
    {
        $td = mcrypt_module_open('blowfish', '', 'ecb', '');

        $data = pack('H*', $text);
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        mcrypt_generic_init($td, $key, $iv);

        $data = mdecrypt_generic($td, $data);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);

        $data = $this->pkcs5_unpad($data);

        return $data;
    }

    private function pkcs5_pad($text, $blocksize)
    {
        $pad = $blocksize - (strlen($text) % $blocksize);

        return $text.str_repeat(chr($pad), $pad);
    }

    private function pkcs5_unpad($text)
    {
        $pad = ord($text[strlen($text) - 1]);
        if ($pad > strlen($text)) {
            return false;
        }
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
            return false;
        }

        return substr($text, 0, -1 * $pad);
    }
}
